#include <app\states\terrainTileState.h>
#include <app\states\statesFactory.h>
#ifdef CLIENT
#include <network\streamingClient.h>
#endif
#include <cache\terrainCacheKey.h>

int terrainTileState::class_type_id = TERRAIN_TILE_STATE_TYPE_ID;

REGISTER_STATE(TERRAIN_TILE_STATE_TYPE_ID, terrainTileState);

sessionState *
terrainTileState::create() {
  return new terrainTileState();
} 

bool 
terrainTileState::isReady() {
  return terrain_tile_desc.status == nTerrainTile::READY;
}

void
terrainTileState::setState(nTerrainTile::eTerrainTile s) {
    
  #ifdef CLIENT
  if (s == nTerrainTile::TRANSFERRED) {
    // notify source of this request that data was downloaded
    caller->get()->terrainDownloaded();
    std::cout << "delete caller" << std::endl;
    delete caller;
  }
  #endif

  terrain_tile_desc.status = s;
}

#ifdef SERVER
void 
terrainTileState::receivedTerrainTile() {

  terrainCacheKey *terr_cache = static_cast<terrainCacheKey *>(cacheKeysFactory::instance().createCacheKey(CACHE_KEY_TERRAIN, parent));
  terr_cache->init(terrain_tile_desc.x, terrain_tile_desc.y, terrain_tile_desc.level);
  terr_cache->userSaveTerrainTileEpmty();
  delete terr_cache;

  setState(nTerrainTile::READY);
}

void 
terrainTileState::requestTerrainTile(int x, int y, int level) {

  if (isReady()) {
    setState(nTerrainTile::TRANSFERRING);
    
    terrain_tile_desc.x = x;
    terrain_tile_desc.y = y;
    terrain_tile_desc.level = level;
  }
}

#endif

#ifdef CLIENT

void 
terrainTileState::requestTerrainTile(int x, int y, int level, boost::shared_ptr<tile> * caller_) {

  if (isReady()) {
    caller = new boost::shared_ptr<tile>(*caller_);

    setState(nTerrainTile::TRANSFERRING);
    
    terrain_tile_desc.x = x;
    terrain_tile_desc.y = y;
    terrain_tile_desc.level = level;
  }
}

void 
terrainTileState::receivedTerrainTile(int x, int y, int level, unsigned char *data, int size) {
  terrain_tile_desc.x = x;
  terrain_tile_desc.y = y;
  terrain_tile_desc.level = level;

  terrainCacheKey *terr_cache = static_cast<terrainCacheKey *>(cacheKeysFactory::instance().createCacheKey(CACHE_KEY_TERRAIN, parent));
  terr_cache->init(x, y, level);
  terr_cache->setData(data, size, false);
  terr_cache->save();
  delete terr_cache;

  setState(nTerrainTile::TRANSFERRED);
}
#endif

int 
terrainTileState::getClassTypeId() {
  return terrainTileState::class_type_id;
}

int 
terrainTileState::getTypeId() {
  return type_id;
}

terrainTileState::terrainTileState() : type_id(TERRAIN_TILE_STATE_TYPE_ID) {

}

terrainTileState::~terrainTileState() {

}
